home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / DataScope 2.0.3 / DataScope2l / DSSource / fcomp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-04  |  10.0 KB  |  449 lines  |  [TEXT/MPS ]

  1. #include    <resources.h>
  2. #include    "macfview.h"
  3.  
  4. /*
  5.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  6.     file fcomp.c
  7.             Equation processing code for DataScope.
  8.             Uses lex and yacc generated parsing system to recognize and
  9.             then compute expressions which may contain arrays.
  10.             
  11.     yfor.lex
  12.         - the lex input which contains the lexical specification for
  13.         what is accepted in the notebook window.
  14.         
  15.     yfor.y
  16.         - the yacc input which uses yfor.lex and parses the simple
  17.         expressions which can be used in the notebook window.
  18.         
  19.     On the Unix side:
  20.         lex yfor.lex
  21.         mv lex.yy.c fparse.l.c
  22.         yacc yfor.y
  23.         mv y.tab.c fparse.y.c
  24.         
  25.         There are some changes to these files required - diff them to
  26.         find out what changes to make.
  27.         
  28.     On the Mac, when you compile fparse.y.c it includes fcomp.c and
  29.     fn_fcomp.c in the compile to produce fparse.y.c.o
  30.     
  31.     The parser builds a parse tree which traverseit() follows to 
  32.     execute the equation.  The memory allocation for arrays and constants
  33.     as sub-elements in the parse tree is VERY tricky.  Study it carefully
  34.     if you are going to modify it.
  35.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  36. */
  37.  
  38. char    *expstr;
  39. int        explen;
  40.  
  41. node    *mkone(oper,lf,rt)
  42.         int        oper;
  43.         node    *lf,*rt;
  44. {
  45.         node    *n;
  46.  
  47.         if (NULL == (n = (node *)NewPtr(sizeof(node))))    return(NULL);
  48.  
  49.         n->left        = lf;
  50.         n->right    = rt;
  51.         n->token    = oper;
  52.         n->var        = NULL;
  53.  
  54.         return(n);
  55. }
  56.  
  57. #ifdef standalone
  58. /*
  59.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  60.     main    main program
  61.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  62. */
  63. main()
  64. {
  65.         int        i;
  66.         char    s[255];
  67.  
  68.         printf("Enter the expression: ");
  69.         gets(s);
  70.         expstr = s;
  71.         printf("yy = %d\n",i=yyparse());
  72.  
  73.         traverse(nlist);
  74.         traverseit(nlist);
  75.  
  76.         printf("\ndone\n");
  77. }
  78. #endif
  79.  
  80. /*
  81.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  82.     execit
  83.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  84. */
  85. execit()
  86. {
  87.         int r;
  88.     
  89.         if (yyparse())    return(-1);
  90.         else
  91.              {r = traverseit(nlist);
  92.               unparse(nlist);                /* free the used memory */
  93.               if (r)    return(1);
  94.               else        return(0);
  95.              }
  96. }
  97.     
  98. /*
  99.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  100.     yyerror        dialog to indicate parsing error
  101.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  102. */
  103. yyerror(es)        char *es;
  104. {
  105. }
  106.  
  107. /*
  108.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  109.     unparse        Free the space used for the linked list of nodes created
  110.                 during the parsing phase.
  111.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  112. */
  113. unparse(n)        node *n;
  114. {
  115.         if (!n)    return;
  116.         unparse(n->left);
  117.         unparse(n->right);
  118.         if (n->var)    DisposPtr(n->var);
  119.         DisposPtr((Ptr) n);
  120. }
  121.     
  122.  
  123. /*
  124.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  125.     Code to traverse a parse tree and calculate results from array
  126.     operand computation.
  127.     
  128.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  129. */
  130.                 
  131. struct workert
  132.         {float    cval;    /* constant value when we are carrying a constant */
  133.         
  134.          int    dimx,
  135.                 dimy;    /* x and y dimensions of the array */
  136.     
  137.          char    talloc,    /* flag byte, is the data array temporarily alloced */
  138.                 stype,    /* structure type flag for this structure */
  139.                 *id;    /* pointer to a string which is an identifier
  140.                            for this structure */
  141.         
  142.          struct    fdatawin 
  143.                 *dat;    /* if appropriate, data from a current window */
  144.         };
  145.  
  146. typedef struct workert WORKING;
  147.  
  148. /* 
  149. *  the valid values for the stype field.
  150. */
  151.  
  152. #define SBLANK  1    /* nothing in structure */
  153. #define SERR    2    /* structure hit an error, no fields are valid except stype */
  154. #define SCONST  3    /* cval field is valid as a float constant */
  155. #define SSTR    4    /* *id field is valid as a string pointer (debugging only) */
  156. #define SARRAY  5    /* dp,xs and ys fields are valid for array */
  157. #define SSTOP   6   /* user level abort found */
  158.  
  159.  
  160. struct    fdatawin *clonedata();
  161.  
  162. /*
  163.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  164.     traverseit    Traverse the parse tree, calculating the variable results.
  165.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  166. */
  167. traverseit(n)
  168.         node *n;
  169. {
  170.         WORKING    a;
  171.         void    fn_mxmn();
  172.     
  173.         a.talloc    = 0;
  174.         a.stype        = SBLANK;
  175.  
  176.         if (!n)                            return(0);
  177.         else if (n->token != TEQUAL)    return(-1);
  178.         else if (!n->left)                return(-1);
  179.         else                            calc(n->left, &a);
  180.  
  181.         /*
  182.         ****************************************************
  183.         arrays:  if borrowing space from a real array, clone
  184.                  it; recalc the max and min of the array;
  185.                  install new variable name and then create
  186.                  the window for it.
  187.         ****************************************************
  188.         */
  189.         if (a.stype == SARRAY)
  190.            {if (!a.dat)        return(-1);
  191.             if (!a.talloc)    a.dat = clonedata(a.dat);
  192.  
  193.                 fn_mxmn(a.dat->vals,(int)(a.dat->xdim * a.dat->ydim),
  194.                             &a.dat->valmax,&a.dat->valmin);
  195.                             
  196.             strncpy(a.dat->dvar,n->var,20);
  197.             ctextwin(a.dat);                /* make it a real window */
  198.            }
  199.         else if (a.stype == SERR)    return(-1);
  200.         else if (a.stype == SCONST)    ans_const(a.cval);
  201.         else;
  202.         
  203.         return(0);
  204. }
  205. /*
  206.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  207.     fn_mxmn        Find and get the max and min of a float array
  208.     
  209.                 p = pointer to the first element of the array
  210.                 n = number of elements in the array
  211.                 a = pointer to the max value
  212.                 b = pointer to the min value
  213.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  214. */
  215. void    fn_mxmn(p,n,a,b)
  216.         register float    *p;
  217.         float            *a,*b;
  218.         int                n;
  219. {
  220.         register float    max,min;
  221.         register float    *q;
  222.  
  223.         q = p + n - 1;
  224.         max = *q;
  225.         min = *q;
  226.         while (p < q)
  227.               {if       (*p > max)    max = *p++;
  228.                else if (*p < min)    min = *p++;
  229.                else                    p++;
  230.               }
  231.         *a = max;
  232.         *b = min;
  233.  
  234.         return;
  235. }
  236.  
  237.  
  238.  
  239. #include    "fn_fcomp.c"
  240.  
  241. /*
  242.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  243.     useor        When doing a calculation, determine which pointers
  244.                     need to be used, malloc whatever temporary space is
  245.                     needed.  If we are already dealing with temporary
  246.                     space, just re-use it, it would be destroyed anyway.
  247.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  248. */
  249. useormalloc(d,a)
  250.         WORKING        *d,*a;
  251. {
  252.         void        ErrorAlert();
  253.     
  254.         a->dimx        = d->dimx;
  255.         a->dimy        = d->dimy;
  256.         a->stype    = SARRAY;
  257.     
  258.         if (d->talloc)
  259.            {a->dat        = d->dat;
  260.             a->talloc    = 1;
  261.             d->talloc    = 0;
  262.               }
  263.         else
  264.              {a->dat = clonedata(d->dat);
  265.               if (!a->dat)
  266.                     {a->stype = SERR;
  267.                   ErrorAlert(GetResource('STR ',1001));
  268.                   return(-1);
  269.                     }
  270.               a->talloc = 1;
  271.              }
  272.         return(0);
  273. }
  274. /*
  275.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  276.     mallocornot        If the calculation requires that the target array
  277.                     be different from the source arrays, this makes 
  278.                     sure that the answer array is its own temporary
  279.                     storage.  Must be called AFTER useormalloc to be
  280.                     accurate.
  281.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  282. */
  283. cloneornot(d,a)
  284.         WORKING        *d,*a;
  285. {
  286.         void        ErrorAlert();
  287.         
  288.     if (a->stype != SARRAY || d->stype != SARRAY)
  289.         return(-1);
  290.  
  291.     if (a->dat == d->dat) {        /* target and source are the same */
  292.     
  293.         a->dimx        = d->dimx;
  294.         a->dimy        = d->dimy;
  295.         a->stype    = SARRAY;
  296.     
  297.         a->dat = clonedata(d->dat);        /* clone it */
  298.         if (!a->dat)
  299.                {a->stype = SERR;
  300.              ErrorAlert(GetResource('STR ',1001));
  301.                  return(-1);
  302.                }
  303.             
  304.          a->talloc = 1;            /* we know to DisposPtr both of them eventually */
  305.          d->talloc = 1;
  306.              
  307.     }
  308.  
  309.     return(0);
  310. }
  311. /*
  312.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  313.     fcompget    Get a character from the expression and pass it to yylex
  314.                 for recognition.
  315.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  316. */
  317. fcompget(a)
  318.         int        a;
  319. {
  320.     
  321.         if (explen <= 0) return(0);
  322.         --explen;
  323.         return((int)tolower((int)*expstr++));
  324. }
  325.  
  326. /*
  327.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  328.     fcompout    Kill all output from lex/yacc.
  329.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  330. */
  331. fcompout(a)
  332.         int        a;
  333. {
  334. }
  335.  
  336.  
  337. /*
  338.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  339.     unknown.  Inform the user and look for an external function to
  340.     handle the request..
  341.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  342. */
  343.  
  344. #include "DScope.h"
  345. #include "resources.h"
  346.  
  347. void 
  348. unknown(s,d,e,a)
  349.     char        *s;
  350.     WORKING        *d,*e,*a;
  351. {
  352.     Handle        rsrcH;
  353.     ProcPtr        pp;
  354.     scope_array    lft,rgt,answer;
  355.     int            ret;
  356.     void        ErrorAlert();
  357.     
  358. /*
  359. *  set up the lft,rgt,answer arrays for the call to the external fn.
  360. */
  361.     lft.kind = DS_CONSTANT;
  362.     lft.cval = 0.0;
  363.     if (d) {
  364.         lft.cval = d->cval;
  365.         if (d->stype == SARRAY) {
  366.             lft.kind = DS_ARRAY;
  367.             lft.nrows = d->dimy;
  368.             lft.ncols = d->dimx;
  369.             lft.vals = d->dat->vals;
  370.             lft.rows = d->dat->yvals;
  371.             lft.cols = d->dat->xvals;
  372.         }
  373.     }
  374.  
  375.     rgt.kind = DS_CONSTANT;
  376.     rgt.cval = 0.0;
  377.     if (e) {
  378.         rgt.cval = e->cval;
  379.         if (e->stype == SARRAY) {
  380.             rgt.kind = DS_ARRAY;
  381.             rgt.nrows = e->dimy;
  382.             rgt.ncols = e->dimx;
  383.             rgt.vals = e->dat->vals;
  384.             rgt.rows = e->dat->yvals;
  385.             rgt.cols = e->dat->xvals;
  386.         }
  387.     }
  388.  
  389.  
  390.     answer.kind = DS_ARRAY;
  391.     answer.vals = a->dat->vals;
  392.     answer.rows = a->dat->yvals;
  393.     answer.cols = a->dat->xvals;
  394.     answer.nrows = a->dimy;
  395.     answer.ncols = a->dimx;
  396.     
  397.     ret = 0;
  398.  
  399.     while (!ret) {
  400.     
  401.         if (rsrcH = getnamedresource('DSfn', s)) {
  402.             HLock(rsrcH);
  403.             pp = (ProcPtr) *rsrcH;
  404.             (*pp)(&lft,&rgt,&answer);
  405.             HUnlock(rsrcH);
  406.             ReleaseResource(rsrcH);
  407.             ret = -1;
  408.     
  409.             
  410.         }
  411.         else {
  412.             ret = findfunction(s);            /* open the correct resource file */
  413.  
  414.             if (ret < 0) {
  415.                 a->stype = SERR;            /* error return */
  416.                 ErrorAlert(GetResource('STR ',1002));
  417.                 return;
  418.             }
  419.             
  420. /*
  421. *  Try the network solution if the user chooses.
  422. */
  423.             if (ret > 0) {
  424.                 netfunction(s,&lft,&rgt,&answer);
  425.                 ret = -1;
  426.             }
  427.             
  428.         }
  429.             
  430.     }
  431.     
  432. /*
  433. *  fill in the values for the return structure from the external fn.
  434. *  If it was an array, then the data is shared, so the external
  435. *  function already changed all of the values we care about.
  436. */
  437.     if (answer.kind < 0) {
  438.         a->stype = SERR;
  439.         ErrorAlert(GetResource('STR ',1003));
  440.     }
  441.     else if (answer.kind == DS_CONSTANT) {
  442.         a->cval = answer.cval;
  443.         a->stype = SCONST;
  444.     }
  445.     
  446.     return;                            /* found and executed function */
  447.  
  448.     
  449. }